package logic

import (
	"context"
	"errors"
	"yuanxin-admin/internal/model"
	"yuanxin-admin/internal/repository"
	"yuanxin-admin/internal/service"
	"yuanxin-admin/internal/vo"

	"github.com/gin-gonic/gin"
)

type SysDeptServiceImpl struct {
}

func NewSysDeptService() service.ISysDeptService {
	return SysDeptServiceImpl{}
}

func (s SysDeptServiceImpl) Remove(c *gin.Context, id string) (bool, error) {
	first, err := repository.SysDept.WithContext(c).
		Select(repository.SysDept.ID, repository.SysDept.ParentID).
		Where(repository.SysDept.ID.Eq(id)).
		First()
	if err != nil {
		return false, err
	}
	if first.ParentID == nil {
		return false, errors.New("该部门为根部门，不能删除！")
	}
	count, err := repository.SysDept.WithContext(c).
		Where(repository.SysDept.ParentID.Eq(id)).
		Count()
	if err != nil {
		return false, err
	}
	if count > 0 {
		return false, errors.New("该部门下有子部门，不能删除！")
	}
	count, err = repository.SysUser.WithContext(c).
		Where(repository.SysUser.DeptID.Eq(id)).
		Count()
	if err != nil {
		return false, err
	}
	if count > 0 {
		return false, errors.New("该部门下有用户，不能删除！")
	}
	resultInfo, err := repository.SysDept.WithContext(c).
		Where(repository.SysDept.ID.Eq(id)).
		Delete()
	return resultInfo.RowsAffected > 0, err

}

func (s SysDeptServiceImpl) Update(c *gin.Context, entity *model.SysDept) (bool, error) {
	updates, err := repository.SysDept.WithContext(c).
		Where(repository.SysDept.ID.Eq(entity.ID)).
		Updates(entity)
	if err != nil {
		return false, err
	}
	return updates.RowsAffected > 0, nil
}

func (s SysDeptServiceImpl) Save(context context.Context, entity *model.SysDept) (bool, error) {
	// 保存部门信息
	err := repository.SysDept.WithContext(context).Create(entity)
	if err != nil {
		return false, err
	}
	return true, nil
}

func (s SysDeptServiceImpl) ListDept(context context.Context) ([]*vo.SysDeptVO, error) {
	var sysDeptVOList []*vo.SysDeptVO
	list, err := repository.SysDept.WithContext(context).Order(repository.SysDept.SortNum.Asc()).Find()
	if err != nil {
		return nil, err
	}
	for _, sysDept := range list {
		sysDeptVO := &vo.SysDeptVO{
			ID:       &sysDept.ID,
			DeptName: &sysDept.DeptName,
			ParentId: sysDept.ParentID,
			SortNum:  sysDept.SortNum,
		}
		sysDeptVOList = append(sysDeptVOList, sysDeptVO)
	}

	var topDepts []*vo.SysDeptVO

	for _, sysDeptVO := range sysDeptVOList {
		if sysDeptVO.ParentId == nil {
			topDepts = append(topDepts, sysDeptVO)
		}
	}
	// 递归设置子部门
	for _, topDept := range topDepts {
		findChildrenDept(topDept, sysDeptVOList)
	}
	return topDepts, err
}

func findChildrenDept(parentDept *vo.SysDeptVO, allDepts []*vo.SysDeptVO) {
	var children []*vo.SysDeptVO

	for _, dept := range allDepts {
		if dept.ParentId != nil && parentDept.ID != nil && *dept.ParentId == *parentDept.ID {
			children = append(children, dept)
		}
	}

	if len(children) > 0 {
		parentDept.Children = children
		for _, child := range children {
			findChildrenDept(child, allDepts)
		}
	}

}
